package com.markerhub.shiro;

import cn.hutool.core.bean.BeanUtil;
import com.markerhub.entity.User;
import com.markerhub.service.UserService;
import com.markerhub.util.JwtUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.security.auth.login.AccountNotFoundException;

@Component
public class AccountRealm extends AuthorizingRealm {
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private UserService userService;
    /**
     * 声明支持的token类型是JwtToken
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    /**
     * 权限规则验证（admin , user）
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    /**
     * 用户授权验证
     * hutool的作用是用Bean.copyProperties(dbUser,accountProfile)将dbUser数据拷给accountProfile对应的字段
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        JwtToken jwtToken= (JwtToken) authenticationToken;
        System.out.println("realm 进行用户信息校验");
        //获得用户id，去数据库查询 Long.parseLong() Long.valueOf()返回包装后的Long
        String id = jwtUtils.getClaimByToken((String) jwtToken.getPrincipal()).getSubject();
        User dbUser = userService.getById(Long.valueOf(id));
        if(dbUser==null){
            throw new UnknownAccountException("账户不存在");
        }
        if(dbUser.getStatus()==-1){
            throw new LockedAccountException("账户锁定中");
        }
        AccountProfile accountProfile=new AccountProfile();
        BeanUtil.copyProperties(dbUser,accountProfile);
        //用户信息，权限，realm名称
        return new SimpleAuthenticationInfo(accountProfile,jwtToken.getCredentials(),getName());
    }

}
